package com.gxa.ehome.aop;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;



//要实现一个切面编程，需要两个注解配合：
@Component
@Aspect
public class LogAspect {
    //设置切点：动态增强的位置（方法）
    //自动记录业务操作的日志：所有的Service的方法
    //自动为所有的业务层添加事务：事务开始（关闭自动提交）
    //在异常的时候事务回滚/在没有异常的时候事务提交/在
    //finally中回收SQLSession（close)

    //找到任意访问权限返回值，在service包中的类的所有方法
    @Pointcut("execution(* com.gxa.ehome.service.*.*(..))")
    public void Pointcut(){

    }
    /*//前置通知
    @Before("Pointcut()")
    public void before(JoinPoint joinPoint){
        joinPoint.getArgs();//获取参数信息
        joinPoint.getTarget();
        System.out.println("这是一个前置通知，Before");
    }
    @AfterReturning("Pointcut()")
    public void afterReturning(){
        System.out.println("这是一个后置通知，AfterReturning");
    }
    //后置抛出通知
    @AfterThrowing("Pointcut()")
    public void afterThrowing(ProceedingJoinPoint proceedingJoinPoint){

        System.out.println("这是一个后置抛出通知，AfterThrowing");
    }
    @After("Pointcut()")
    public void after(){
        System.out.println("这是一个后置通知，after");
    }*/

    //环绕通知，相当于将上述4中通知组合在一起使用
    //一版不会让环绕通知和其他通知共同使用
    @Around("Pointcut()")
    public Object around(ProceedingJoinPoint joinPoint){
        Object proceed=null;
        try {
            System.out.println("前置通知");
            proceed = joinPoint.proceed();//代理方法的执行位置
            System.out.println("后置返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("后置抛出通知");
        }finally {
            System.out.println("后置通知");
        }
        return proceed;
    }
}
